package org.NooLab.itexx.app.controller;

import java.util.ArrayList;

import org.NooLab.itexx.ITexxWindowCommons;
import org.NooLab.utilities.datatypes.IndexDistance;
import org.NooLab.utilities.datatypes.IndexedDistances;
import org.NooLab.utilities.logging.PrintLog;

public class FoundListGenerator {

	
	SessionManager sessionMgr;
	private ITexxWindowCommons appCommons;
	private PrintLog out;
	private ScoredSerDocuments scoredSerDocs;
	
	private IndexedDistances panelMap;
	private FoundResultsGuiUpdater guiUpdater;
	
	ArrayList<String> excludedDomains;
	
	double currentScoreMinimum = 0.0;
	
	// ========================================================================
	public FoundListGenerator( SessionManager sMgr,
							   GeneralQueueServiceIntf generalQueueServiceIntf) {
		sessionMgr = sMgr;
		appCommons = sessionMgr.appCommons;
		
		excludedDomains = appCommons.getAppProperties().getIniPreferences().getExcludedDomains() ;
		
		// late init needed... panelMap = appCommons.getModelController().getPanelMap() ;
		// we arrive here through ITexxWindowCommons.setReferences()
		out = sessionMgr.out;
	}
	// ========================================================================
	
	
	public void updateRawResults( ScoredSerDocuments rawSerItems){
		
		if (appCommons.getAppProperties().getIniPreferences().getShowRawSer()<=0){
			return;
		}
		
		int n = rawSerItems.size();
		for (int i = 0; i < n; i++) {
			
		}
		
	}
	
	/**
	 * 
	 * invoked by threaded process :  ScoredSerDocuments::ListService
	 * 
	 * ScoredSerDocuments are created in turn by the scoring routine upon completion of score calculation
	 * the serItems are transposed into ScoredSerDocuments:items
	 *  
	 */
	public void update() { //use observer pattern
		// 
		ScoredSerDocument scDoc ;
		double minscore ;
		IndexDistance panelMapItem ;
		int ix ;
		scoredSerDocs = sessionMgr.getScoredSerDocuments();
		
		int n = scoredSerDocs.items.size();
		
		n = scoredSerDocs.getFreshItemsIndices().size();
		
		if ((n<=0)) {// && ( sessionMgr.getStateOnProcess()>= SessionManagerIntf._REQUEST_RAID_COMPLETED)){
			//return;
		}
		
		int remainingPages = appCommons.getSearchEngineResults().size();
		if (remainingPages > 0){
			out.printErr(2, ">>>>> FoundListGenerator: awaiting completion of page retrieval..."); 
			//return;
		}
		
		if (remainingPages==0){
			//panelMap.clear() ;
		}
		
		if (n!=0){ 
			out.printErr(2, ">>>>> FoundListGenerator: now there are "+n+" scored documents waiting for being prepared for display...");
		}
		
		// if we have at least 3 items, even when not finished yet, we digest...
		if ((n<3) && (sessionMgr.statusFlag != SessionManagerIntf._REQUEST_RAID_COMPLETED)){ return; } 
		
		if ((panelMap==null) && (n>0)){
			// late initialization...
			panelMap = appCommons.getModelController().getPanelMap() ;
			guiUpdater = appCommons.getResultsGuiUpdater();
		}
		
		// now handling the items
		// there are two basic conditions: all panels present or number of used panels < maxNumberOfPanels (from properties)  
		
		// ----------------------------------------------------------------
											out.printErr(2, ">>>>> FoundListGenerator: going to digest "+n+" scored documents for display...");
		
		for (int i = 0; i < n; i++) {
			
			if (scoredSerDocs.getFreshItemsIndices().size()>0){
			
				// ix = scoredSerDocs.getFreshItemsIndices().get(0);
				// scoredSerDocs.getFreshItemsIndices().remove(0);
				ix = scoredSerDocs.getFreshItemsIndices().get(i);
				
			} else{ 
				break; // instead of continue
			}
			
			if (ix<0){ continue;}
			scDoc = scoredSerDocs.get(ix);
			String urlStr = scDoc.getDocUrl() ;
if (urlStr.toLowerCase().contains("hiddensee")){			
	int k;
	k=0;
}			
//excluded? already seen? =>=> last-minute-blocking...
			boolean hb = urlIsAllowedByFilters(urlStr,scoredSerDocs,i-1);
			if (hb==false){
				continue ;
			}
			if (scDoc.getScore()<0.0){
				continue;
			}
			
			// we have to check whether we have to update one of the panelMap references 
			// already points to a scoredSerDoc that contains the same url 
			// 
			int r = checkSerDocAgainstPanels( scDoc);
			
			if (r<0){
				out.print(2, "checking item for display: alreday seen");
				continue;
			}
			
			// DEBUG: collect urls to a global list & file, append.
			
			appCommons.getModelController().getGlobalUrlList().add( new IndexDistance(panelMap.size(),i,scDoc.getScore(),urlStr) ) ; 
			
			// -------------------------------------------------------
			// do we still have less panels defined than allowed ? 
			if (panelMap.size() <= guiUpdater.maxNumberOfPanels) {

				// simply adding, and filling some book keeping variables
				minscore = panelMap.getMinimum(0.0, 0); // infimum (>), offset

				if (panelMap.size() == 0){
					if (scDoc.getScore()>0)currentScoreMinimum = scDoc.getScore();
				} else {
					if ((scDoc.getScore()>0) && (currentScoreMinimum > scDoc.getScore())) {
						currentScoreMinimum = scDoc.getScore();
					}
				}

				// scheduledForRemoval , checkedForDisplay
				// we still can simply add : physical index, logical index
				panelMapItem = new IndexDistance( panelMap.size(), ix, scDoc.getScore());
				panelMap.add(panelMapItem);

			} 
			/*
			else {
				// all slots are filled, so we have to remove the one with lowest score
				// check score

				int minix = panelMap.getIndexOfMinimum(0.0,0) ;
				minscore = panelMap.getItem(minix).getDistance() ; // infimum (>), offset

				// we introduce the new item only if it is better than the current lowest
				if (minscore < scDoc.getScore()){
					
					panelMap.removeItem(minix);
					
					panelMapItem = new IndexDistance( panelMap.size(), ix, scDoc.getScore());
					
					currentScoreMinimum = panelMap.getItem(minix).getDistance() ;
				}
				
			}
			 */
		} // i-> all getFreshItemsIndices;
		
		out.delay(1500);
		if (scoredSerDocs.getFreshItemsIndices().size()==n){
			// scoredSerDocs.getFreshItemsIndices().clear();
			
			// 1, serItem.getGuid(), 
			// sessionMgr.setStateOnProcess(1,"" , SessionManagerIntf._REQUEST_RAID_COMPLETED) ; 
		}
											out.printErr(2, ">>>>> FoundListGenerator: items handling done, now sorting and sending to the display process...");
											
											
		// remove double entries ? checking again excluded domains ?
											
		if ((panelMap!=null) && (panelMap.size()>1)){  
			panelMap.sort(-1); // -1 = largest first
			panelMap.renewEnumeration(1,0); // a: 1 = first index, 2=secondary index, b: base of enum, mostly 0, or 1
		}
		// there the number of physical panels should get
		appCommons.getWindowGui().setStatusLabelText("");
		
		guiUpdater.refreshItems( scoredSerDocs, panelMap,remainingPages==0 );
		
		if (remainingPages==0){
			appCommons.getSearchEngineResults().clear();
		}
	}


	private int checkSerDocAgainstPanels(ScoredSerDocument scDoc) {
		// 
		boolean rB=false;
		int result=0;
		
		IndexDistance panelMapItem ;
		ScoredSerDocument serDoc ;
		
		for (int i=0; i< panelMap.size();i++){
			panelMapItem = panelMap.getItem(i) ;
			int ix = panelMapItem.getIndex2() ;
			serDoc = scoredSerDocs.get(ix);
			
			if (serDoc.getDocUrl().contentEquals( scDoc.getDocUrl() )){
				result = -i;
				break;
			}
		}
		
		return result;
	}
	
	
	private boolean urlIsAllowedByFilters( String urlStr, 
										   ScoredSerDocuments scoredDocs, 
										   int lastIndex) {
		// 
		boolean rB=true;
		String docurl;
		int ix=-1;
		
		
		for (int i=0;i<scoredDocs.size();i++){
			if (i>=lastIndex){
				break;
			}
			
			ScoredSerDocument scd = scoredDocs.get(i);
			docurl = scd.getDocUrl() ;
			if (docurl.contentEquals(urlStr)){
				rB=false;
				break;
			}
		}
		
		if (rB){
if (urlStr.contains("youtube")){
	int k;
	k=0;
}
			if ((excludedDomains!=null) && (excludedDomains.size()>0)){
				String ds = appCommons.strgutil.getDomainFromUrl(urlStr);
				boolean hb ;
				hb = excludedDomains.indexOf(ds)>=0;
				if (hb==false){
					ds = ds.replace("www.", ""); 
					ix = excludedDomains.indexOf(ds);
					hb = ix>=0;
				}
				if (hb){
					rB=false;
				}
			}
		}
		
		ix=ix+1-1;
		return rB;
	}


	public double getCurrentScoreMinimum() {
		return currentScoreMinimum;
	}


	public void setCurrentScoreMinimum(double currentScoreMinimum) {
		this.currentScoreMinimum = currentScoreMinimum;
	}

}
